# -----------------------------------------------------------------------------
# Copyright (c) 2011, MIPS Technologies, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright
#     notice, this list of conditions, and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions, and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of MIPS Technologies, Inc. nor the
#     names of its contributors may be used to endorse or promote products
#     derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MIPS TECHNOLOGIES, INC. BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES, LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# -----------------------------------------------------------------------------
'''
Created on May 18, 2011

@author: rkotler
'''

def opt_has_arg(defn):
    if "arg" in defn:
        return True;
    else:
        return False;

def is_option(arg):
    if (arg[0] == '-'):
        return True
    else:
        return False

class GnuLanguageRules: 
                               
    def __init__(self):
        pass
    
    _languages = {}
    
    _suffix_mapping = {};
    
    def add_language(self, name):                       
        self._languages[name] = "";
        
        
    def languages(self):
        return self._languages;
    
    def add_suffix(self, suffix, lang):
        self._suffix_mapping[suffix] = lang
        
    def find_language(self, name):
        if name in self._suffix_mapping:
            return self._suffix_mapping[name]
        else:
            return "none" 
        
    def suffix_mappings(self):
        return self._suffix_mapping    
            
class GnuParser:
    '''
    classdocs
    '''

    short_opt = []
    long_opt = {}
    opt_kind = {}
    
    def __init__(self):
        '''
        Constructor
        '''
#       self.short_opt = (0,)*128*0
#      
#   def add_short_opt(self, letter, defn):
#       self.long_opt[letter] = 1
#        pass
   
    def add_long_opt(self, name, defn):
        self.long_opt[name] = opt_has_arg(defn)
        pass
    
    def add_opt(self, name, defn):
        #print "add opt:", name
        self.add_long_opt(name, defn)
        if "kind" in defn:
            self.opt_kind[name] = defn["kind"]
        else:
            self.opt_kind[name] = ""
                
    def get_opt(self):
        return self.long_opt
    
    def find_opt(self, opt):
        #print "finding: ", opt
        if opt in self.long_opt:
            return True;
        else:
            return False;
    
    def opt_has_arg(self, opt):
        return self.long_opt[opt]
    
    def get_opt_kind(self, name):
        return self.opt_kind[name]
    
    
    # this is not most efficient way to do this.
    # but in general it will be fast and few options will
    # perform badly from this.
    # i'll make it better if this driver gets accepted
    # split opt based on some prefix
    #
    def find_suffix(self, opt):
        for i in range(len(opt) -1):
            prefix = opt[0:i+1];
            if (self.find_opt(prefix)):
                return [prefix, opt[i+1:]]

        assert False, "option not found: " + opt
        
    def get_opt_defn(self, opt):
        return self.long_opt[opt]
    
    #
    # returns tuple
    # [options, first non option, remaining args]
    #
    def do_parse (self, args):
        options = []
        files = []
        prev = ""
        for arg in args:
            if (prev != ""):
                # we had an argument
                options.append([prev, arg])
                prev = ""
            else:    
                if is_option(arg):
                    #print "option arg: " ,arg
                    if self.find_opt(arg):
                        #print "find_opt: " + arg;
                        if self.opt_has_arg(arg):
                            prev = arg;                    
                        else:
                            options.append(arg)
                    else:
                        x = self.find_suffix(arg);
                        #print "find_suffix_opt:", x, 
                        options.append(x)
                        #print x
                else:
                    files.append(arg)
        if (prev != ""):
            print "unfinished arg: ", prev
        return [options, files]
    
